#include "modulewidget.h"
#include "ui_modulewidget.h"

#include "imodule.h"
#include "tableinfomodle.h"
#include "sqltool.h"
#include "CustomTableDelegate.h"
#include "cadinterface.h"

#include <QTabWidget>
#include <QTableView>
#include <QMessageBox>
#include <QHeaderView>
#include <QFile>


struct ModuleWidgetPrivate{
    IModule* module;
    QList<QTableView*> views;
    bool create = true; ///<是否是创建
    QVariantMap currentInfo = {}; ///<当前项的所有的数据
    QTabWidget* editTabWgt = nullptr;
    QTabWidget* tableTabWgt = nullptr;
    QStackedWidget* editSWgt = nullptr;

    QList<QVariantMap> infos;///所有的数据

    QSet<int> selectRows;
    int oldEditTabIndex = 0;

    IModuleEditFrameInterface* currentEditWgtByActionName(const QString& actName) {
        if (module->menuInfos().isEmpty()) return nullptr;
        return module->getEditWgtByName(actName);
    }

    IModuleEditFrameInterface* currentEditWgtByTableName(const QString& tbName) {
        if (module->menuInfos().isEmpty()) return nullptr;

        auto ews = module->editWidgets();
        for (const auto& ew : ews) {
            if (ew->dbName() == tbName)
                return ew;
        }
        return nullptr;
    }

    bool isSubNew() {
        return !module->menuInfos().isEmpty();
    }


};


ModuleWidget::ModuleWidget(QWidget *parent)
    : IModuleForm(parent)
    , ui(new Ui::moduleWidget)
{
    ui->setupUi(this);

    m_d = new ModuleWidgetPrivate();
    connect(ui->pBtn_ok, &QPushButton::clicked, this, &ModuleWidget::save);
    connect(ui->pBtn_cancel, &QPushButton::clicked, this, &ModuleWidget::cancel);
    connect(ui->pBtn_find, &QPushButton::clicked, this, &ModuleWidget::findResult);
    connect(ui->pBtn_findCancel, &QPushButton::clicked, this, &ModuleWidget::cancel);
}

ModuleWidget::~ModuleWidget()
{
    delete ui;
}

/**
 * @brief 设置当前模块并初始化界面
 * @param module 要设置的模块指针，不能为空
 *
 * 该方法会：
 * 1. 设置当前模块
 * 2. 从数据库获取所有数据
 * 3. 初始化表格视图
 * 4. 初始化编辑界面
 * 5. 初始化查找界面
 */
void ModuleWidget::setIModule(IModule *module)
{
    if (!module) return;
    m_d->module = module;
    getAllDbInfos();

    // 获取表格数据模型并初始化表格视图
    // 如果有多于一个表格模型，使用QTabWidget组织
    auto infoModels = module->tableInfoModels();
    const auto infoSize = infoModels.size();
    if (infoSize > 1) {
        QTabWidget* tabWgt = new QTabWidget(this);
        int index = 0;
        for (const auto& infom : infoModels) {
            tabWgt->addTab(createTableWidget(index, infom), infom.title);
            ++index;
        }
        setTabWgtStyleSheet(tabWgt);
        m_d->tableTabWgt = tabWgt;
        ui->vlayout_table->addWidget(tabWgt);
    } else if (infoSize == 1) {
        const auto& infom = infoModels[0];
        auto iw = createTableWidget(0, infom);
        ui->vlayout_table->addWidget(iw);
    }


    // 获取编辑控件并初始化编辑界面
    // 如果有多于一个表格模型，使用QTabWidget组织
    auto ews = module->editWidgets();

    auto acts = module->menuInfos();
    if (acts.isEmpty()) {
        if (ews.size() > 1) {
            QTabWidget* tabWgt = new QTabWidget(this);
            for (const auto& ew : ews) {
                ew->setCallback([this]()->QVariantMap& { return this->editInfo(); });
                tabWgt->addTab(ew, ew->title());
            }
            setTabWgtStyleSheet(tabWgt);
            m_d->editTabWgt = tabWgt;
            connect(tabWgt, &QTabWidget::currentChanged, this, &ModuleWidget::editUiChange);
            ui->vlayout_edit->addWidget(tabWgt);
        } else if (ews.size() == 1) {
            const auto& ew = ews[0];
            ew->setCallback([this]()->QVariantMap& { return this->editInfo(); });
            ui->vlayout_edit->addWidget(ew);
        }
    } else {
        m_d->editSWgt = new QStackedWidget(this);
        for (const auto& ew : ews) {
            m_d->editSWgt->addWidget(ew);
        }
        ui->vlayout_edit->addWidget(m_d->editSWgt);
    }



    // 初始化查找界面
    if (auto findWgt = module->findWidget())
        ui->vlayout_find->addWidget(findWgt);
    // 默认显示表格视图
    ui->stackedWidget->setCurrentIndex(0);

    module->selectInfoCallback([this]()->QList<QVariantMap> {
        return this->getSelectInfos();
    });

}

void ModuleWidget::menuItemTriggered_createNew(const QString &actionName)
{
    m_d->currentInfo = {};
    auto ews = m_d->module->editWidgets();
    for (const auto ew : ews) {
        ew->reInitUI();
    }
    m_d->create = true;
    auto current = ui->stackedWidget->currentIndex();
    ui->stackedWidget->setCurrentIndex(1);
    auto acts = m_d->module->menuInfos();
    if (acts.isEmpty()) {
        if (current == 0 && m_d->tableTabWgt) {
            auto index = m_d->tableTabWgt->currentIndex();
            if (m_d->editTabWgt) {
                m_d->editTabWgt->setCurrentIndex(index);
            }
            m_d->oldEditTabIndex = index;
        } else if (current == 2) {
            if (m_d->editTabWgt) {
                m_d->editTabWgt->setCurrentIndex(0);
            }
            m_d->oldEditTabIndex = 0;
        }

    } else {
        auto wgt = m_d->module->getEditWgtByName(actionName);
        if (wgt) {
            m_d->editSWgt->setCurrentWidget(wgt);
        } else {
            QMessageBox::critical(this, "错误", "没有匹配的数据");
        }
    }

}

void ModuleWidget::menuItemTriggered_modify()
{
    auto row = selectRow();
    if (row == -1) return;
    ui->stackedWidget->setCurrentIndex(1);
    int index = 0;
    if (m_d->tableTabWgt) {
        index = m_d->tableTabWgt->currentIndex();
    }
    m_d->oldEditTabIndex = index;
    editUiShow(row, index);
}

void ModuleWidget::menuItemTriggered_delete()
{

    //发送取消高亮信号
    int index = 0;
    if (m_d->tableTabWgt) {
        index = m_d->tableTabWgt->currentIndex();
    }
    auto tableView = m_d->views.at(index);

    auto selIndexs = tableView->selectionModel()->selectedIndexes();
    if (selIndexs.isEmpty()) return;

    QSet<int> rows;
    for (const auto& modelIndex : selIndexs) {
        auto row = modelIndex.row();
        rows.insert(row);
    }

    auto model = tableView->model();
    const auto& infos = m_d->infos;
    QMap<QString, QMultiMap<QString, QVariant>> delInfos;
    for (const auto& row : rows) {
        auto modelIndex = model->index(row, 0);
        emit onMenuItemTriggered_highlight(modelIndex,"deSelectHighLight");//cancel highlight request
        //删除被选中的行
        if (row >= infos.size()) return;
        const auto& dbInfo = infos[row];

        if (dbInfo.contains("Name")) {
            auto dbName = m_d->module->dbTableName();
            if (m_d->isSubNew()) {
                dbName = dbInfo["DBNAME"].toString();
            }
            auto& conditionMap = delInfos[dbName];
            conditionMap.insert("Name", dbInfo.value("Name"));
        }
    }
    Sqltool::instance().changeInfoDb();
    for (auto it = delInfos.begin(); it != delInfos.end(); ++it) {
        Sqltool::instance().deleteItemsByConditions(it.key(), *it);
    }
    getAllDbInfos();
    updateTableInfo();
}

void ModuleWidget::menuItemTriggered_highlight(const QModelIndex &index,
                                               QString highLight_onoff,
                                               QList<QString> listHighLightType,
                                               QString selectDeselect)
{
    if (!index.isValid()) return;
    auto row = index.row();
    if (row >=  m_d->infos.size()) return;
    const auto& data = m_d->infos[row];
    const auto& highLightTypes = m_d->module->highlightTypes();
    QList<QString> highLightIDs;
    if (!highLightTypes.isEmpty()) {
        for(const auto& type : listHighLightType)
        {
            if (highLightTypes.contains(type)) {
                const auto& dv = highLightTypes[type];
                const auto& id = data.value(dv).toString();
                if (!id.isEmpty())
                    highLightIDs.push_back(id);
            }
        }
        if(selectDeselect=="selectHighLight")
        {
            CADInterface::instance().fibHighLightArray(highLightIDs);
        }
        if(selectDeselect=="deSelectHighLight")
        {
            CADInterface::instance().fibunHighLightArray(highLightIDs);
        }
    }

    m_d->module->processHighlightData(data, selectDeselect == "selectHighLight");

}

void ModuleWidget::menuItemTriggered_find()
{
    if (auto findWgt = m_d->module->findWidget()) {
        findWgt->reInitUi();
        ui->stackedWidget->setCurrentIndex(2);
    }
}

void ModuleWidget::menuItemTriggered_Find_From_Geom()
{
    ui->stackedWidget->setCurrentIndex(0);
    getAllDbInfos();
    if (m_d->module->hasFindGeoSupport()) {
        const wchar_t* filterType = L"HybridShapeAssemble,HybridShapePlaneOffset,HybridShapeCurvePar,HybridShapeBoundary";
        char Find_From_Geom[256] = {0};  // 输出缓冲区
        // 调用 SelectionToID 函数
        CADInterface::instance().fibSelectiontoID(filterType,Find_From_Geom);
        QList<QVariantMap> finds;
        for (const auto& info : m_d->infos) {
            if(Find_From_Geom==info.value("LayupSurface").toString()||
                Find_From_Geom==info.value("NetBoundary").toString()||
                Find_From_Geom==info.value("ExtBoundary").toString())
                finds.append(info);
        }
        m_d->infos = finds;
    }
    updateTableInfo();
}

void ModuleWidget::menuItemTriggered_createBasedon()
{
    auto row = selectRow();
    if (row == -1) return;
    ui->stackedWidget->setCurrentIndex(1);
    int index = 0;
    if (m_d->tableTabWgt) {
        index = m_d->tableTabWgt->currentIndex();
    }
    m_d->oldEditTabIndex = index;
    editUiShow(row, index, false);
}

QWidget *ModuleWidget::createTableWidget(int id, const TableInfoData &tableData)
{
    QTableView* view = new QTableView(this);
    TableInfoModel* model = new TableInfoModel(tableData.headers);
    model->setCanSelected(false);
    QVector<QVariantMap> rets = tableInfo(tableData.table2dbKey);
    model->updateInfo(rets);
    view->setModel(model);
    view->setSelectionBehavior(QAbstractItemView::SelectItems);
    view->verticalHeader()->setVisible(false);

    QHeaderView *header = view->horizontalHeader();
    header->setMinimumHeight(30);

    header->setStyleSheet(
        "QHeaderView::section {"
        "    background-color: #282B34;"
        "    color: #9198A3;"
        "    font-family: Arial;"
        "    font-size: 10pt;"
        "    border-top: 0px;"
        "    border-left: 0px;"
        "    border-right: 2px solid #9198A3;"
        "    border-bottom: 0px;"
        "}"
        "QHeaderView::section:selected {"
        "    color: white;"
        "}"
        );

    // 从qss文件加载样式
    QFile styleFile(":/styles/table_styles.qss");
    if (styleFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QString styleSheet = QLatin1String(styleFile.readAll());
        // header->setStyleSheet(styleSheet);
        view->setStyleSheet(styleSheet);
        styleFile.close();
    }

    CustomTableDelegate *tableDelegate = new CustomTableDelegate(this);
    view->setItemDelegate(tableDelegate);



    for (int i = 0; i < tableData.headers.size(); ++i) {
        if (i < tableData.colSetting.size()) {
            const auto& settingsR = tableData.colSetting[i];
            view->setColumnWidth(i, settingsR.initialWidthR);
            header->setSectionResizeMode(i, settingsR.resizeModeR);
            // 使用信号槽机制确保最小宽度
            connect(header, &QHeaderView::sectionResized, [header, i, settingsR](int logicalIndexr, int oldSizer, int newSizer){
                if (logicalIndexr == i && newSizer < settingsR.minWidthR) {
                    header->resizeSection(logicalIndexr, settingsR.minWidthR);
                }
            });
        }
    }

    m_d->views.append(view);
    connect(view, &QTableView::doubleClicked, this, [this, id](const QModelIndex &index){
        ui->stackedWidget->setCurrentIndex(1);
        m_d->oldEditTabIndex = id;
        editUiShow(index.row(), id);
    });

    connect(view->selectionModel(), &QItemSelectionModel::selectionChanged,this,&ModuleWidget::selectionChangedTableView );

    return view;
}

void ModuleWidget::editUiShow(int row, int id, bool isEdit)
{
    const auto infos = m_d->infos;
    if (row >= infos.size()) return;
    m_d->create = !isEdit;
    const auto& info= infos[row];
    m_d->currentInfo = info;

    if (m_d->isSubNew()) {
        auto dbName = info["DBNAME"].toString();
        auto ew = m_d->currentEditWgtByTableName(dbName);
        if (ew) {
            isEdit ? ew->editUI(info) : ew->createBaseOn(info);
            m_d->editSWgt->setCurrentWidget(ew);
        }
    } else {

        auto ews = m_d->module->editWidgets();
        for (const auto ew : ews) {
            isEdit ? ew->editUI(info) : ew->createBaseOn(info);
        }
        if (m_d->editTabWgt) m_d->editTabWgt->setCurrentIndex(id);
    }

}

void ModuleWidget::editUiChange(int index)
{
    auto ews = m_d->module->editWidgets();
    if (m_d->oldEditTabIndex != index && m_d->oldEditTabIndex < ews.size()) {
        auto ew = ews.at(m_d->oldEditTabIndex);
        ew->getData(m_d->currentInfo);
    }

    m_d->oldEditTabIndex = index;

    // int i = 0;
    // for (const auto ew : ews) {
    //     if (i != index) {
    //         ew->getData(m_d->currentInfo);
    //     }
    //     ++i;
    // }
    auto ew = ews.at(index);
    ew->updateInfo(m_d->currentInfo);

    //获取当前数据
    ew->getData(m_d->currentInfo);

}

void ModuleWidget::save()
{
    auto ews = m_d->module->editWidgets();
    QVariantMap info;
    auto dbName = m_d->module->dbTableName();
    if (m_d->isSubNew()) {
        auto ew = dynamic_cast<IModuleEditFrameInterface*>(m_d->editSWgt->currentWidget());
        ew->getData(info);
        dbName = ew->dbName();
    } else {
        IModuleEditFrameInterface* curEw = nullptr;
        if (m_d->editTabWgt)
            curEw = dynamic_cast<IModuleEditFrameInterface*>(m_d->editTabWgt->currentWidget());
        for (const auto ew : ews) {
            if (!ew->validateForm()) return;
            if (curEw == ew) continue;
            ew->getData(info);
        }
        if (curEw)
            curEw->getData(info);
    }


    Sqltool::instance().changeInfoDb();

    QPair<QString, QVariant> pair{"Name", info["Name"]};
    const auto& infoOne = Sqltool::instance().selectOne(dbName, pair);
    if (infoOne.isEmpty()) {
        if (info.contains("id")) {
            info.remove("id");
        }
        Sqltool::instance().insertDb(dbName, info);
    } else {
        QVariantMap conditions;
        if (info.contains("id")) {
            conditions.insert("id", info["id"]);
        } else if (info.contains("Name")) {
            conditions.insert("Name", info["Name"]);
        }
        Sqltool::instance().updateDb(dbName, info, conditions);

    }

    //保存数据
    // if (m_d->create) {
    //     if (info.contains("id")) {
    //         info.remove("id");
    //     }
    //     Sqltool::instance().insertDb(m_d->module->dbTableName(), info);
    // } else {
    //     QVariantMap conditions;
    //     if (info.contains("id")) {
    //         conditions.insert("id", info["id"]);
    //     } else if (info.contains("Name")) {
    //         conditions.insert("Name", info["Name"]);
    //     }
    //     Sqltool::instance().updateDb(m_d->module->dbTableName(), info, conditions);
    // }
    reInitUI();
    getAllDbInfos();
    updateTableInfo();
    ui->stackedWidget->setCurrentIndex(0);

}

void ModuleWidget::cancel()
{
    reInitUI();
    ui->stackedWidget->setCurrentIndex(0);
}

void ModuleWidget::reInitUI()
{

    getAllDbInfos();
    updateTableInfo();
    ui->stackedWidget->setCurrentIndex(0);
    m_d->currentInfo = {};
    m_d->selectRows = {};
    auto ews = m_d->module->editWidgets();
    for (const auto ew : ews) {
        ew->reInitUI();
    }
    m_d->create = true;
}

bool ModuleWidget::isNeedSave()
{
    clear();
    if (ui->stackedWidget->currentIndex() == 1) return true;
    return false;
}

void ModuleWidget::clear()
{
    auto row = selectRow();
    if (row == -1) return;

    //发送取消高亮信号
    int index = 0;
    if (m_d->tableTabWgt) {
        index = m_d->tableTabWgt->currentIndex();
    }
    auto tableView = m_d->views.at(index);

    auto model = tableView->model();
    auto modelIndex = model->index(row, 0);
    emit onMenuItemTriggered_highlight(modelIndex,"deSelectHighLight");//cancel highlight request

}

QList<QVariantMap> ModuleWidget::getSelectInfos()
{
    int index = 0;
    if (m_d->tableTabWgt) {
        index = m_d->tableTabWgt->currentIndex();
    }
    auto tableView = m_d->views.at(index);

    auto selIndexs = tableView->selectionModel()->selectedIndexes();
    if (selIndexs.isEmpty()) return {};

    QSet<int> rows;
    for (const auto& modelIndex : selIndexs) {
        auto row = modelIndex.row();
        rows.insert(row);
    }

    QList<QVariantMap> rets;
    for (const auto& sel :  rows) {
        rets << m_d->infos[sel];
    }
    return rets;
}

int ModuleWidget::selectRow()
{
    return m_d->selectRows.empty() ? -1 : *(m_d->selectRows.begin());
    /*
    auto sIndex = ui->stackedWidget->currentIndex();
    if (sIndex != 0) {
        QMessageBox::information(this, "提示", tr("请选取一个数据进行处理"));
        return  -1;
    }
    int index = 0;
    if (m_d->tableTabWgt) {
        index = m_d->tableTabWgt->currentIndex();
    }
    auto tableView = m_d->views.at(index);
    QItemSelectionModel* selectionModel = tableView->selectionModel();

    // 获取选中的行索引
    QModelIndexList selectedRows = selectionModel->selectedRows();
    QSet<int> rows;
    for (const QModelIndex& index : selectedRows) {
        rows.insert(index.row());
    }
    return rows.empty() ? -1 : *(rows.begin());
   */
}

void ModuleWidget::updateTableInfo()
{
    auto infoModels = m_d->module->tableInfoModels();
    for (int i = 0; i < m_d->views.size(); ++i) {
        auto view = m_d->views[i];
        const auto& infoModel = infoModels[i];
        auto tableModel = dynamic_cast<TableInfoModel*>(view->model());
        QVector<QVariantMap> rets = tableInfo(infoModel.table2dbKey);
        tableModel->updateInfo(rets);
    }
}

void ModuleWidget::getAllDbInfos()
{
    if (m_d->module == nullptr) return;
    Sqltool::instance().changeInfoDb();
    if (m_d->isSubNew()) {
        auto ews = m_d->module->editWidgets();
        m_d->infos.clear();
        for (const auto ew : ews) {
            auto infos = Sqltool::instance().selectAllByTableName(ew->dbName());
            for (auto& info : infos)
            {
                info["DBNAME"] = ew->dbName();
                info["ObjectType"] = ew->objectType();
            }
            m_d->infos.append(infos);
        }

    } else
        m_d->infos = Sqltool::instance().selectAllByTableName(m_d->module->dbTableName());
}

QVector<QVariantMap> ModuleWidget::tableInfo(const QMap<QString, QString> &keys)
{
    QVector<QVariantMap> rets;
    for (const auto& model : m_d->infos) {
        QVariantMap info;
        for (auto it = keys.begin(); it != keys.end(); ++it) {
            info[it.key()] = model[it.value()];
        }
        rets.push_back(info);
    }
    return rets;
}

QVariantMap& ModuleWidget::editInfo()
{
    // auto ews = m_d->module->editWidgets();
    // for (const auto ew : ews) {
    //     ew->getData(m_d->currentInfo);
    // }
    return m_d->currentInfo;
}

void ModuleWidget::refreshViews()
{

}

void ModuleWidget::setTabWgtStyleSheet(QTabWidget *wgt)
{
    wgt->setStyleSheet(
        "QTabWidget {"
        "    border: none;"
        "    background-color: #515A65;"
        "}"
        "QWidget {"
        "        background-color: #515A65;"
        "}"
        "QTabBar::tab {"
        "    background-color: #414B59;"
        "    font-family: Arial;"
        "    font-size: 10pt;"
        "    color: white;"
        "    text-align: center;"
        "    width: 150px;"
        "    height: 20px;"
        "    margin-right: 2px; /* 设置标签页之间的间隔 */"
        "    border: none; /* 去掉标签页之间的边框 */"
        "}"
        "/* 选中的标签页 */"
        "QTabBar::tab:selected {"
        "background: #515A65;"
        "    font-family: Arial;"
        "    font-size: 10pt;"
        "color: white;"
        "    text-align: center;"
        "}"
        "/* 鼠标悬停时的标签页 */"
        "QTabBar::tab:hover {"
        "background: #515A65;"
        "    font-family: Arial;"
        "    font-size: 10pt;"
        "color: white;"
        "    text-align: center;"
        "}"
        "/* 非选中的标签页 */"
        "QTabBar::tab:!selected {"
        "    margin-top: 0px; /* 调整非选中标签页的上下间距 */"
        "    color: #9198A3;"
        "    background: #414B59;"
        "}"
        "QTabWidget::pane{"
        "    border:none;"
        "}"
        );


}

void ModuleWidget::findResult()
{
    ui->stackedWidget->setCurrentIndex(0);
    if (!m_d->module) return;
    if (auto findWgt = m_d->module->findWidget()) {
        auto ids = findWgt->selectedIds();
        if (ids.isEmpty()) return;
        getAllDbInfos();
        QList<QVariantMap> finds;
        for (const auto& info : m_d->infos) {
            if (!info.contains("id")) continue;
            auto id = info.value("id").toInt();
            if (!ids.contains(id)) continue;
            finds.append(info);
        }
        m_d->infos = finds;
        updateTableInfo();
    }
}

void ModuleWidget::selectionChangedTableView(const QItemSelection &selected, const QItemSelection &deselected)
{
    m_d->selectRows.clear();
    if(selected.count()>0)
    {

        for(const QModelIndex & index:selected.indexes())
        {
            emit onMenuItemTriggered_highlight(index,"selectHighLight");//高亮请求信号
            m_d->selectRows.insert(index.row());
        }
    }
    if(deselected.count()>0)
    {
        for(const QModelIndex & index:deselected.indexes())
        {
            emit onMenuItemTriggered_highlight(index,"deSelectHighLight");//cancel highlight request
        }
    }
}
